#include "widget.h"
#include "ui_widget.h"
#include <QThread>
#include "client_manager.h"
Widget::Widget(QWidget *parent) : QWidget(parent), ui(new Ui::Widget) {
  ui->setupUi(this);
  setWindowTitle("UDP服务端");

  connect( &m_udp,  & QUdpSocket::readyRead , this  ,  &Widget::slotReadyRead);

  //在QT5中存在
  //QAbstractSocket::error() 函数和 QUdpSocket::error同名
  //直接写会产出歧义，究竟是信号error 还是函数erro，所以不能这么写
  //connect(&m_udp , &QUdpSocket::error ,this ,&MainWindow::slotError);
  //而所有应 带上参数
  //  connect(&m_udp , SIGNAL(error(QAbstractSocket::SocketError)) ,this , SLOT(slotError(QAbstractSocket::SocketError)));
  //Qt6解决了这个问题，取消了error这个信号，改成了errorOccurred
  //connect(&m_udp , SIGNAL(errorOccurred(QAbstractSocket::SocketError)) ,this , SLOT(slotError(QAbstractSocket::SocketError)));
  connect(&m_udp , &QUdpSocket::errorOccurred ,this , [this](QAbstractSocket::SocketError err){slotError(err);});

}

Widget::~Widget() {
  delete ui;
}

void Widget::on_btnStart_clicked()
{
    if (!m_start)
    {
        QString ip = ui->lineEditIP->text();
        uint port = ui->lineEditPort->text().toUInt();
        QHostAddress  addr(ip );
        // 绑定指定IP与端口
        bool   rel = m_udp.bind(addr,port, QUdpSocket::ShareAddress);
        if(rel)
        {
            showMessage("绑定成功，等待接收UDP数据");
            m_start = true;
        }else {
           showMessage("绑定失败" + m_udp.errorString());
        }
    }
    else
    {
          m_udp.close();
          //清理所有客户端
          ClientManager::getInstance().closeAllClients();
          showMessage("停止服务");
          m_start = false;
    }

}

void  Widget::slotReadyRead()
{
    //是否有数据抵达
    while ( m_udp.hasPendingDatagrams())
    {
        //获取要读取数据的大小
        int size = m_udp.pendingDatagramSize();

        //定义一块缓冲区，来接收数据
        QByteArray arr;
        arr.resize(size);

        QHostAddress  addr; //发送方的IP
        quint16  port;//发送方的端口

        //接收数据的同时，获取到对方的IP与端口
        int rel = m_udp.readDatagram(arr.data(),size, &addr,&port);

        if(rel > 0)
        {
            QString msg = arr;
            QHostAddress  ipv4 (addr.toIPv4Address());
            QString str = QString("接收到%1:%2的消息: %3")
                              .arg(ipv4.toString()).arg(port).arg(msg);

            showMessage(str);

            //保存客户端的IP与端口，方便群发数据给客户端
            //重复则插入不进去
            ClientManager::getInstance().addClient(ipv4 ,port) ;
            qDebug() << "客户端数量"<<ClientManager::getInstance().clientCount();

        }

    }
}


void Widget::slotError(QAbstractSocket::SocketError  err)
 {
   QString  strErr = QMetaEnum::fromType<QAbstractSocket::SocketError>().valueToKey( err );
   QString str =QString("错误码：%1描述：%2").arg( strErr ).arg(  m_udp.errorString() ) ;
   showMessage( str );
 }

void Widget::showMessage(const QString &info) {
  ui->messageShoxEdit->appendPlainText(info);
}

void Widget::on_btnSend_clicked() {
  QString msg = ui->messageEdit->text();
  QByteArray array = msg.toUtf8();
  ClientManager::getInstance().sendData(m_udp,array);
}
